package com.panasonic.web.service.impl;

import com.panasonic.web.domain.cms.CmsPermission;
import com.panasonic.web.domain.cms.CmsUser;
import com.panasonic.web.mapper.CmsPermissionMapper;
import com.panasonic.web.mapper.CmsUserMapper;
import com.panasonic.web.service.ICmsUserService;
import com.panasonic.web.util.CmsSecurityUtils;
import com.panasonic.web.util.JavaMailService;
import com.panasonic.web.vo.CmsBatchStatusVo;
import com.panasonic.web.vo.ForgetPasswordVo;
import com.panasonic.web.vo.ResetPasswordVo;
import com.panasonic.common.core.redis.RedisCache;
import com.panasonic.common.exception.CustomException;
import com.panasonic.common.utils.DateUtils;
import com.panasonic.common.utils.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.mail.MessagingException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 用户Service业务层处理
 *
 * @author lwf
 * @date 2021-11-13
 */
@Service
public class CmsUserServiceImpl implements ICmsUserService {
    private static final String USER_FORGET_PASSWORD_ID = "user_forget_password_id:";
    private static final String USER_ADMIN_TYPE = "0";

    @Autowired
    private CmsUserMapper cmsUserMapper;
    @Autowired
    private CmsPermissionMapper cmsPermissionMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private JavaMailService javaMailService;

    /**
     * 查询用户
     *
     * @param id 用户ID
     * @return 用户
     */
    @Override
    public CmsUser selectCmsUserById(Long id) {
        return cmsUserMapper.selectCmsUserById(id);
    }

    /**
     * 查询用户列表
     *
     * @param cmsUser 用户
     * @return 用户
     */
    @Override
    public List<CmsUser> selectCmsUserList(CmsUser cmsUser) {
        if (cmsUser.getPermissionIds() != null && cmsUser.getPermissionIds().length > 0) {
            Long[] ids = cmsPermissionMapper.selectCmsPermissionByCid(cmsUser.getPermissionIds(), cmsUser.getPermissionIds().length);
            if (ids != null && ids.length > 0) {
                cmsUser.setIds(ids);
            } else {
                List<CmsUser> cmsUsers = new ArrayList<>();
                return cmsUsers;
            }
        }

        List<CmsUser> cmsUsers = cmsUserMapper.selectCmsUserList(cmsUser);
        if (CollectionUtils.isNotEmpty(cmsUsers)) {
            long[] ids = cmsUsers.stream().mapToLong(s -> s.getId()).toArray();
            List<CmsPermission> permissions = cmsPermissionMapper.selectCmsPermissionByIds(ids);
            if (CollectionUtils.isNotEmpty(permissions)) {
                cmsUsers.stream().forEach(s -> {
                    List<CmsPermission> cmsPermissions = permissions.stream().filter(p -> p.getUserId().equals(s.getId())).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(cmsPermissions)) {
                        s.setCmsPermissionList(cmsPermissions);
                    }
                });
            }
        }

        return cmsUsers;
    }

    /**
     * 新增用户
     *
     * @param cmsUser 用户
     * @return 结果
     */
    @Transactional
    @Override
    public int insertCmsUser(CmsUser cmsUser,boolean send) {
        CmsUser existUser = null;
        if (cmsUser.getType() > 0) {
            existUser = cmsUserMapper.selectCmsUserByName(cmsUser.getUsername());
        } else {
            existUser = cmsUserMapper.selectCmsUserByUsername(cmsUser.getUsername(), cmsUser.getType().toString());
        }


        if (existUser != null) {
            throw new CustomException("用户名已存在！");
        }
        cmsUser.setCreateTime(DateUtils.getNowDate());
        cmsUser.setCreateBy(CmsSecurityUtils.getUsername());
        String password = cmsUser.getPassword();
        cmsUser.setPassword(CmsSecurityUtils.encryptPassword(cmsUser.getPassword()));
        int rows = cmsUserMapper.insertCmsUser(cmsUser);
        if (cmsUser.getPan() == 1) {
            cmsUser.setPanId(cmsUser.getId());
            cmsUserMapper.updateCmsUser(cmsUser);
        }
        insertCmsPermission(cmsUser);

        if(send==true){
            //发送创建成功邮件通知
            javaMailService.sendCreateUserEmail(cmsUser,password,1);
        }

        return rows;
    }

    /**
     * 修改用户
     *
     * @param cmsUser 用户
     * @return 结果
     */
    @Transactional
    @Override
    public int updateCmsUser(CmsUser cmsUser,boolean send) {
        int existCount = 0;
        if (cmsUser.getType() > 0) {
            existCount = cmsUserMapper.selectCmsUserByUsernameNotEqIdGtType(cmsUser.getId(), cmsUser.getUsername());
        } else {
            existCount = cmsUserMapper.selectCmsUserByUsernameNotEqId(cmsUser.getId(), cmsUser.getUsername(), cmsUser.getType().toString());
        }
        if (existCount > 0) {
            throw new CustomException("用户名已经存在!");
        }
        String password = "";
        if (StringUtils.isNotEmpty(cmsUser.getPassword())) {
            password = cmsUser.getPassword();
            cmsUser.setPassword(CmsSecurityUtils.encryptPassword(cmsUser.getPassword()));
        }
        cmsUser.setUpdateBy(CmsSecurityUtils.getUsername());
        cmsUser.setUpdateTime(DateUtils.getNowDate());
        cmsUserMapper.deleteCmsPermissionByUserId(cmsUser.getId());
        insertCmsPermission(cmsUser);
        int rows = cmsUserMapper.updateCmsUser(cmsUser);
        if(send==true) {
            //发送创建成功邮件通知
            javaMailService.sendCreateUserEmail(cmsUser, password, 2);
        }
        return rows;
    }

    /**
     * 批量删除用户
     *
     * @param ids 需要删除的用户ID
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteCmsUserByIds(Long[] ids) {
        cmsUserMapper.deleteCmsPermissionByUserIds(ids);
        return cmsUserMapper.deleteCmsUserByIds(ids);
    }

    /**
     * 删除用户信息
     *
     * @param id 用户ID
     * @return 结果
     */
    @Override
    public int deleteCmsUserById(Long id) {
        cmsUserMapper.deleteCmsPermissionByUserId(id);
        return cmsUserMapper.deleteCmsUserById(id);
    }

    /**
     * 新增全新啊信息
     *
     * @param cmsUser 用户对象
     */
    public void insertCmsPermission(CmsUser cmsUser) {
        List<CmsPermission> cmsPermissionList = cmsUser.getCmsPermissionList();
        Long id = cmsUser.getId();
        if (StringUtils.isNotNull(cmsPermissionList)) {
            List<CmsPermission> list = new ArrayList<CmsPermission>();
            for (CmsPermission cmsPermission : cmsPermissionList) {
                cmsPermission.setUserId(id);
                cmsPermission.setUpdateBy(CmsSecurityUtils.getUsername());
                cmsPermission.setUpdateTime(DateUtils.getNowDate());
                list.add(cmsPermission);

            }
            if (list.size() > 0) {
                cmsUserMapper.batchCmsPermission(list);
            }
        }
    }

    @Override
    public CmsUser selectUserByUsername(String username) {
        String name = username.substring(0, username.indexOf("&"));
        String type = username.substring(username.indexOf("&") + 1);
        if (USER_ADMIN_TYPE.equals(type)) {
            return cmsUserMapper.selectCmsUserByUsername(name, type);
        }
        return cmsUserMapper.selectCmsUserByName(name);
    }

    @Override
    public int changeStatus(CmsBatchStatusVo cmsBatchStatusVo) {
        return cmsUserMapper.changeStatus(cmsBatchStatusVo.getIds(),
                cmsBatchStatusVo.getStatus(),
                CmsSecurityUtils.getUsername(),
                DateUtils.getNowDate());
    }

    @Override
    public int updateLoginTime(long id) {
        return cmsUserMapper.updateLoginTime(id,
                DateUtils.getNowDate());
    }

    @Transactional(rollbackFor = CustomException.class)
    @Override
    public void insertBatchCmsUser(List<CmsUser> cachedDataList) {
        cachedDataList.stream().forEach(s -> {
            cmsUserMapper.insertCmsUser(s);
            insertCmsPermission(s);
        });
        cmsUserMapper.updateBatchPanId();
    }

    @Override
    public void forgetPassword(ForgetPasswordVo forgetPasswordVo) throws MessagingException {
        CmsUser cmsUser = cmsUserMapper.selectCmsUserByUsernameAndEmail(forgetPasswordVo);
        if (cmsUser == null) {
            throw new CustomException("用户名或者邮箱错误");
        }
        String code = UUID.randomUUID().toString();
        String key = USER_FORGET_PASSWORD_ID + code;
        String lastKey = USER_FORGET_PASSWORD_ID + cmsUser.getId();
        forgetPasswordVo.setCode(code);
        javaMailService.sendForgetPasswordEmail(forgetPasswordVo);
        redisCache.setCacheObject(key, forgetPasswordVo, 30, TimeUnit.MINUTES);
        redisCache.setCacheObject(lastKey, code);
    }

    @Override
    public void resetPassword(ResetPasswordVo resetPasswordVo) {
        String key = USER_FORGET_PASSWORD_ID + resetPasswordVo.getCode();
        ForgetPasswordVo forgetPasswordVo = redisCache.getCacheObject(key);
        if (forgetPasswordVo == null) {
            throw new CustomException("验证码已经过期");
        } else {
            redisCache.deleteObject(key);
        }

        CmsUser cmsUser = cmsUserMapper.selectCmsUserByUsernameAndEmail(forgetPasswordVo);
        String lastKey = USER_FORGET_PASSWORD_ID + cmsUser.getId();

        String lastCode = redisCache.getCacheObject(lastKey);
        if (!resetPasswordVo.getCode().equals(lastCode)) {
            throw new CustomException("验证码已经过期");
        } else {
            redisCache.deleteObject(lastCode);
        }
        cmsUser.setPassword(CmsSecurityUtils.encryptPassword(resetPasswordVo.getPassword()));
        cmsUser.setUpdateBy(cmsUser.getUsername());
        cmsUser.setUpdateTime(DateUtils.getNowDate());
        cmsUserMapper.updateCmsUser(cmsUser);
    }
}
